package com.gyj.server.core;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * 注册表数据类型
 * 包含服务的信息和续约信息（Lease）
 * @author Gao
 * @date 2021/6/26
 */
public class ServiceInstance {

    private static final Logger logger = LogManager.getLogger(ServiceInstance.class);

    /**
     * 判断一个服务实例不再存活的时间
     */
    private static final long NOT_ALIVE_PERIOD = 90 * 1000L;

    /**
     * 服务名称
     */
    private String serviceName;

    /**
     * ip地址
     */
    private String ip;

    /**
     * 主机名
     */
    private String hostName;

    /**
     * 端口号
     */
    private Integer port;

    /**
     * 服务实例id，一个服名可能对应多台机器实例
     */
    private String serviceInstanceId;

    /**
     * 服务续约实体类
     */
    private Lease lease;

    public ServiceInstance() {
        this.lease = new Lease();
    }

    /**
     * 续约
     */
    public void renew() {
        if (this.lease != null) {
            this.lease.renew();
        }
    }

    /**
     * 判断服务实例是否存活
     * @return
     */
    public boolean isAlive() {
        return this.lease.isAlive();
    }

    private class Lease {

        /**
         * 最近一次心跳的时间
         */
        private volatile long latestHeartbeatTime = System.currentTimeMillis();

        /**
         * 服务续约，更新心跳时间为当前时间
         */
        public void renew() {
            this.latestHeartbeatTime = System.currentTimeMillis();
            logger.info("服务续约instanceId:{}, 时间:{}", serviceInstanceId, latestHeartbeatTime);
        }

        /**
         * 判断服务是否存活
         * @return
         */
        public boolean isAlive() {
            if (System.currentTimeMillis() - latestHeartbeatTime > NOT_ALIVE_PERIOD) {
                logger.info("服务续约，服务instanceId:{}不再存活", serviceInstanceId);
                return false;
            }
            return true;
        }
    }

    public Lease getLease() {
        return lease;
    }

    public void setLease(Lease lease) {
        this.lease = lease;
    }

    public String getServiceName() {
        return serviceName;
    }

    public void setServiceName(String serviceName) {
        this.serviceName = serviceName;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getServiceInstanceId() {
        return serviceInstanceId;
    }

    public void setServiceInstanceId(String serviceInstanceId) {
        this.serviceInstanceId = serviceInstanceId;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    }
}
